package com.net128.beatportapps.downloader;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

public class DownloadStatistics {
	private class TimingInfo {
		private long time;
		private long downloaded;
		public TimingInfo(long time, long downloaded) {
			super();
			this.time = time;
			this.downloaded = downloaded;
		}
		public long getDownloaded() {
			return downloaded;
		}
		public long getTime() {
			return time;
		}	
	}
	
	private List <TimingInfo> timings=new ArrayList<TimingInfo>();
	private long total=0;
	private final static int timingInterval=300;
	private final static int maxTimings=60;
	private double rate;
	
	public synchronized int getETA(long downloaded, long total) {
		int n=timings.size();
		long time=System.currentTimeMillis();
		if(n==0 || time-timings.get(n-1).getTime()>=timingInterval) {
			timings.add(new TimingInfo(time,downloaded));
			this.total=total;
		}
		if(timings.size()>maxTimings) {
			timings.remove(0);
		}
		
		return eta();
	}

	public synchronized String getETAString(long downloaded, long total) {
		int eta=getETA(downloaded, total);
		if(eta==0 || timings.size()==0) {
			return "";
		}
		long offset=(Calendar.getInstance().get(Calendar.ZONE_OFFSET));
		SimpleDateFormat sdf = new SimpleDateFormat("HH'h' mm'm' ss's'");
		String result=sdf.format(eta*1000-offset);
		while(result.startsWith("00") && result.length()>4) {
			result=result.substring(4);
		}
		if(result.startsWith("0")) {
			result=result.substring(1);
		}
		return result;
	}

	public synchronized String getETAStringFull(long downloaded, long total) {
		String etaString=getETAString(downloaded, total);
		if(etaString.length()==0) {
			return etaString;
		}
		return etaString+" ("+Math.round(rate/1024)+" K/s)";
	}
	
	private int eta() {
		if(timings.size()<=1) {
			if(timings.get(0).getDownloaded()>=total) {
				return 0;
			}
			return (int)((total-timings.get(0).getDownloaded())/10000+1);
		}
		TimingInfo t1=timings.get(0);
		TimingInfo t2=timings.get(timings.size()-1);
		long left=total-t2.getDownloaded();
		rate=(t2.getDownloaded()-t1.getDownloaded())*1000.0/(t2.getTime()-t1.getTime());
		return (int)Math.round(left/rate);
	}
	
	private void test() throws Exception {
		int step=1000;
		int duration=23;
		int total=(int)(duration*step*1000.0/230);
		int downloaded=0;
		while(true) {
			System.out.println(getETAStringFull(downloaded, total));
			downloaded+=step;
			if(downloaded>=total) {
				break;
			}
			Thread.sleep(230);
		}
	}
	
	public static void main(String [] args) throws Exception {
		new DownloadStatistics().test();
	}
}
